package com.codeape.number.base.mvvm.command;

import androidx.annotation.NonNull;

import java.util.concurrent.Callable;

public class Command<T> {
    private Action execute0 = null;
    private Consumer<T> execute1 = null;
    private Callable<Boolean> canExecute0 = null;

    public Command(Action execute) {
        this.execute0 = execute;
    }

    Command(Consumer<T> execute) {
        this.execute1 = execute;
    }

    /**
     * @param execute     callback for event
     *                    *
     * @param canExecute0 if this function return true the action execute would be invoked! otherwise would't invoked!
     */
    Command(Action execute, Callable<Boolean> canExecute0) {
        this.execute0 = execute;
        this.canExecute0 = canExecute0;
    }

    /**
     * @param execute     callback for event,this callback need a params
     *                    *
     * @param canExecute0 if this function return true the action execute would be invoked! otherwise would't invoked!
     */
    Command(Consumer<T> execute, Callable<Boolean> canExecute0) {
        this.execute1 = execute;
        this.canExecute0 = canExecute0;
    }

    public void execute() {
        if (execute0 != null && canExecute0()) {
            try {
                execute0.run();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }


    private Boolean canExecute0() {
        if (canExecute0 == null) {
            return true;
        }
        try {
            return canExecute0.call();
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }
    }

    void execute(T parameter) {
        if (execute1 != null && canExecute0()) {
            try {
                execute1.accept(parameter);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    interface Consumer<T> {
        /**
         * Consume the given value.
         *
         * @param t the value
         * @throws Exception on error
         */
        void accept(@NonNull T t) throws Exception;
    }
}

